package moonlit.chill.pay.controller;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import moonlit.chill.pay.asyncFactory.AsyncFactory;
import moonlit.chill.pay.asyncFactory.AsyncFactoryManager;
import moonlit.chill.pay.cache.PayConfigDataCache;
import moonlit.chill.pay.cache.PayMappingsDataCache;
import moonlit.chill.pay.exception.PayException;
import moonlit.chill.pay.factory.PayFactory;
import moonlit.chill.pay.service.BeforeLaunchPayHandler;
import moonlit.chill.pay.service.PayStrategy;
import moonlit.chill.pay.vo.PayResult;
import moonlit.chill.pay.vo.RequestResult;
import moonlit.chill.pay.vo.TradeParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**
 * @author MoonlitChill
 * @date 2024/4/15 11:13
 */
@Slf4j
@RestController
@RequestMapping("/pay")
public class PayController {

    @Autowired
    private PayFactory payFactory;

    @Autowired
    private PayConfigDataCache payConfigDataCache;

    @Autowired
    private PayMappingsDataCache payMappingsDataCache;

    @Autowired
    private BeforeLaunchPayHandler beforeLaunchPayHandler;

    @PostMapping
    public RequestResult pay(@RequestBody @Valid TradeParam tradeParam) {
        try {
            String code = payMappingsDataCache.getCode(null, tradeParam.getPayType(), tradeParam.getPayChannel());
            if (StrUtil.isEmpty(code)) {
                throw new PayException("发起支付异常，请联系管理员");
            }
            payConfigDataCache.setCode(code);
            PayStrategy payStrategy = payFactory.getPayStrategy(tradeParam.getPayType() + "-" + tradeParam.getPayChannel());
            if (payStrategy != null) {
                boolean flag = beforeLaunchPayHandler.beforeLaunchPayHandler(tradeParam);
                if (flag) {
                    PayResult<?> result = payStrategy.payMethod(tradeParam);
                    if (result.isSuccess()) {
                        AsyncFactoryManager.me().execute(AsyncFactory.launchPaySuccessHandle(result, tradeParam));
                        return RequestResult.success(result.getResult());
                    } else {
                        return RequestResult.error(result.getMessage());
                    }
                }
            } else {
                log.info("发起支付获取payStrategy为空");
                return RequestResult.error("发起支付异常，请联系管理员");
            }
        } catch (Exception e) {
            log.error("发起支付产生异常", e);
            return RequestResult.error(e instanceof PayException ? e.getMessage() : "发起支付异常，请联系管理员");
        }
        return RequestResult.error("发起支付失败");
    }
}
